#! /usr/bin/python
#coding: utf-8
import sqlite3
#import apsw
import xml.etree.cElementTree as ET




def execute_query(dbcursor, table_name, conditions = None, list_conditions = None):
    query = "select * from " + table_name
    if conditions:
        query += ' where '
        query += ' and '.join(map(lambda x: x[0] + "='" + x[1] + "'", conditions.iteritems()))

    if list_conditions:
        if conditions:
            query += ' and '
        else:
            query += ' where '

        query += ' and '.join(
            map(lambda x: x[0] + ' in (' + ' ,'.join(
                map(lambda y: "'" + y + "'", x[1])) + ')',
                list_conditions.iteritems()))

    results = dbcursor.execute(query).fetchall()
    return results

#a = {'a':'b', 'c':'d'}
#b = {'e': ['f','g'], 'h': ['i']}
#
#execute_query(None,'alpha',a)
#execute_query(None,'alpha',list_conditions = b)
#execute_query(None,'alpha',a,b)

class LinguisticDatabase:
    def __init__(self, dbpath):
        self.dbconnection = sqlite3.connect(dbpath)
#        ###
#        ### Backup to memory
#        ###
#
#        # We will copy the disk database into a memory database
#
#        memcon=apsw.Connection(":memory:")
#
#        # Copy into memory
#        with memcon.backup("main", self.dbconnection, "main") as backup:
#            backup.step() # copy whole database in one go

        self.dbcursor = self.dbconnection.cursor()

        #B = Basis()
        #tcolor = TSort(B, 'цвет')
        #phys_object = TSort(B, 'физ.об.')
        #green = InformationUnit(B, 'зеленый', tcolor)
        #fcolor = Function(B,'цвет', phys_object, tcolor)

        #KEquals(KFunction(Function,None))
        #self.lsd = {
        #    'зеленый': KFunction('Цвет',None,'Зеленый')
        #
        #}
        #self.dpf = PrepositionalFramesDictionary(dbpath)
        #self.dvpf = VerbPrepositionalFramesDictionary(dbpath)
        #self.ss = SortsSystem(dbpath)
        #self.rqs = Rqs(dbpath)

    def query_ldb(self, table_name, conditions=None):
        return execute_query(self.dbcursor, table_name, conditions)





class LexicoSemanticDictionary:
    """Lexico-semantic dictionary"""
    def __init__(self, dbpath):
        self.con = sqlite3.connect(dbpath)
        self.cursor = self.con.cursor()

    def insert_entry(self, word, part, sem, sorts, comment):
        """
            Добавляет новую запись в лексико-семантический словарь.
        """
        query = "insert into lsd VALUES(NULL, '" + word + "', '" + part + "', '" + sem + "', '"
        for i in sorts:
            query += i + "', '"
        query += comment + "')"
        self.cursor.execute(query)
        self.con.commit()
        return 'Запись добавлена в словарь!'

    def get_entries(self, parameters):
        return execute_query(self.cursor, 'lsd', parameters)

    def get_sems_by_word(self, word, part=None, semrepr=None, sorts=None):
        """
            Возвращает все записи из семантико-синтаксического словаря,
            соответствующие указанным параметрам поиска.

        """
        query = "select * from lsd where word='" + word.lower() + "'"
        self.cursor.execute(query)
        results = []
        for i in self.cursor:
            results.append(i)
        return results

class SortsSystem:
    def __init__(self, dbpath, xmlpath):
        self.con = sqlite3.connect(dbpath)
        self.cursor = self.con.cursor()
        self.xmltree = ET.parse(xmlpath)
        self.doc = self.xmltree.getroot()

    def is_generalization(self, sort1, sort2):
        print self.doc.find('object')



    def is_concretisation(self, sort1, sort2):
        """
              Checks whether sort2 is a child of sort1
        """
        if sort1 == sort2: return True
        sequence = []
        cur = sort1
        do = True
        while do:
            query = "select * from sort_system where sort='" + cur + "'"
            self.cursor.execute(query)
            for i in self.cursor:
                sequence.append(cur)
                if i[1] is None:
                    do = False
                    break
                cur = i[1]
                break
            else: break
            if cur is None: break
        if sort2 in sequence:
            return True
        return False


class PrepositionalFramesDictionary:
    """Dictionary of prepositional semantic-syntactic frames"""

    def __init__(self, dbpath):
        self.con = sqlite3.connect(dbpath)
        self.cursor = self.con.cursor()

    def insert_frame(self, prep, fsort, ssort, grcase, rel, expl):
        """Inserts new frame into the dictionary"""
        query = "insert into PrepositionalFramesDictionary VALUES(NULL, '" + prep + "', '" + fsort
        query += "', '" + ssort + "', " + grcase + ", '" + rel + "', '"
        query += expl + "')"
        self.cursor.execute(query)
        self.con.commit()
        return u'Запись добавлена в словарь!'




class VerbPrepositionalFramesDictionary:
    """Dictionary of verbal-prepositional semantic-syntactic frames"""

    def __init__(self, dbpath):
        self.con = sqlite3.connect(dbpath)
        self.cursor = self.con.cursor()

    def insert_frame(self, semsit, form, reflexivity, voice, prep, grcase, sort, thematic_role, expl):
        """Inserts new frame into the dictionary"""
        query = "insert into VerbarlPrepositionalFramesDictionary VALUES(NULL, '" + semsit + "', '" + form
        query += "', '" + reflexivity + "', '" + voice + "', '" + prep + "', '"
        query += grcase + "', '" + sort + "', '" + thematic_role + "', '" + expl + "')"
        self.cursor.execute(query)
        self.con.commit()
        return u'Запись добавлена в словарь!'

    def get_frames_by_semsit(self, semsit):
        """
              Возвращает все записи из словаря предложных фреймов,
              соответствующие указанным параметрам поиска.
          """
        query = "select * from dvpf where semsit='" + semsit + "'"
        self.cursor.execute(query)
        results = []
        for i in self.cursor:
            results.append(i)
        return results






    def get_all_frames(self):
        "Возвращает все записи словаря глагольно-предложных семантико-синтаксических фреймов"
        query = "select * from dvpf"
        self.cursor.execute(query)
        results = []
        for i in self.cursor:
            results.append(i)
        return results


class Rqs:
    """Система вопросительных словосочетаний"""

    def __init__(self, dbpath):
        self.con = sqlite3.connect(dbpath)
        self.cursor = self.con.cursor()

    def insert_frame(self, prep, qw, relq):
        """Inserts new frame into the dictionary"""
        query = "insert into Rqs VALUES(NULL, '" + prep + "', '" + qw + "', '" + relq + "')"
        self.cursor.execute(query)
        self.con.commit()
        return 'Запись добавлена в словарь!'

    def get_frames(self, qw, prep=None):
        """Возвращает все фреймы, содержащие на указанных параметров"""
        if prep is None:
            query = "select * from dpf where prep=NULL"
        else:
            query = "select * from dpf where "
            query += "prep ='" + prep + "' AND qw='" + qw + "'"

        self.cursor.execute(query)
        results = []
        for i in self.cursor:
            results.append(i)
        return results

    def get_array(self):
        "Возвращает все записи словаря"
        query = "select * from Rqs"
        self.cursor.execute(query)
        results = []
        for i in self.cursor:
            results.append({'prep': i[1], 'qswd': i[2], 'relq': i[3]})
        return results


####
####VERY USEFUL CODE: AN EXPERIMENTATION TO PUT ALGORITHM ON PYKLIB
####
#from PyKlib.kbasic import *
##initialize basis
#B = Basis()
#ref = InformationUnit(B, 'некоторый', B.int1)
#def _ref(concept):
#    return KIntentionalQuantifier(ref, concept)
##initialize sorts
#sdate = TSort(B, 'зндаты')
#sprice = TSort(B,'знцены')
#physob = TSort(B, 'физоб')
#stimed = TSort(B,'времоб') #объект существующий в промежутке времени
#sgeoobj = TSort(B,'геогроб') #объект на карте мира
#spricedobj = TSort(B, 'ценоб') #объект, который можно купить
#sdestinobj = TSort(B, 'обсконпун') #объект с конечным пунктом
#snamedobj = TSort(B, 'именоб') #объект с именем
#sname = TSort(B, 'знимени') #значение имени
#
#scurrency = TSort(B, 'знвалюты')
#snumber = TSort(B, 'натчисло')
##initialize inforamtionUnits
#
#africa = InformationUnit(B,'Африка',TConcept(sgeoobj))
#ruble = InformationUnit(B,'Рубль', scurrency)
#summa = InformationUnit(B,'сумма', TConcept(sprice))
#number = InformationUnit(B,'30000', snumber)
#trip = InformationUnit(B, 'поездка', TConcept(TElementary([stimed,sgeoobj,sprice])))
#continent = InformationUnit(B, 'континент', TConcept(TElementary([sgeoobj, snamedobj])))
#country = InformationUnit(B, 'страна', TConcept(TElementary([sgeoobj, snamedobj])))
#
#fcurrency = Function(B,'Валюта',[sprice], [scurrency])
#fdate = Function(B,'Дата', [stimed], [sdate])
#fdestination = Function(B,'Конечный пункт', [sdestinobj], [sgeoobj])
#fprice = Function(B, 'Цена', [spricedobj], [sprice])
#fnumber = Function(B, 'Число',[sprice],[snumber])
#fname = Function(B, 'Название', [snamedobj],[sname])
#
#ksumma = KConcept(summa,{})
#ktrip = KConcept(trip,{})
#kafrica = _ref(KConcept(continent,{fname:africa}))
#
#print ksumma, ksumma.type, ktrip.type
#
#LSD = {
#    'тур':ktrip,
#    'Африка': kafrica
#}